package network;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.net.InetSocketAddress;

/**
 * @author fank
 * @date 2018/03/08
 */
public class NetServer {
    public final static String MSG_SPLIT = "@";
    public final static String MSG_END = "@&";
    @Value("${port:6012}")
    private int port;
    @Autowired
    private ServerHandler serverHandler;

    public void start() throws Exception {
        // 引导辅助程序
        ServerBootstrap b = new ServerBootstrap();
        // 通过nio方式来接收连接和处理连接
        EventLoopGroup group = new NioEventLoopGroup();
        // handler处理线程
        EventExecutorGroup handlerExecutor = new DefaultEventExecutorGroup(4);
        b.group(group);
        // 设置nio类型的channel
        b.channel(NioServerSocketChannel.class);
        // 设置监听端口
        b.localAddress(new InetSocketAddress(port));
        // 有连接到达时会创建一个channel
        b.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                /*ch.pipeline().addLast(new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS));*/
                // 截止符号
                /*ByteBuf buf = Unpooled.copiedBuffer(MSG_END.getBytes());
                ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf));*/

                ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4));
                // 设置编码
                ch.pipeline().addLast(new StringDecoder());
                ch.pipeline().addLast(handlerExecutor, "myHandler", serverHandler);
            }
        });

        // 配置完成，开始绑定server，通过调用sync同步方法阻塞直到绑定成功
        ChannelFuture f = b.bind().sync();
        //System.out.println(NetServer.class.getName() + " started and listen on " + f.channel().localAddress());
        // 应用程序会一直等待，直到channel关闭
        //f.channel().closeFuture().sync();
        //关闭EventLoopGroup，释放掉所有资源包括创建的线程
        //group.shutdownGracefully().sync();
    }
}
